/*
 * Copyright (C) 2015 yixun All Rights Reserved.
 *
 * AreaServiceImpl.java
 */
package com.yixun.qfbao.api.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yixun.qfbao.api.service.*;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.apidto.base.CommonResDTO;
import com.yixun.qfbao.config.M2ApiConfig;
import com.yixun.qfbao.config.V10ApiConfig;
import com.yixun.qfbao.constant.StringConstant;
import com.yixun.qfbao.dao.DepartmentDao;
import com.yixun.qfbao.model.*;
import com.yixun.qfbao.model.dto.*;
import com.yixun.qfbao.model.enums.*;
import com.yixun.qfbao.service.CompanyService;
import com.yixun.qfbao.service.DocumentService;
import com.yixun.qfbao.service.*;
import com.yixun.qfbao.util.*;
import com.yixun.qfbao.xf.model.CustomerPremises;
import com.yixun.qfbao.xf.model.FollowUpList;
import com.yixun.qfbao.xf.model.Premises;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.dto.FollowUpListDto;
import com.yixun.qfbao.xf.model.enums.*;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import com.yixun.qfbao.xf.service.FollowUpListService;
import com.yixun.qfbao.xf.service.PremisesService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * [文件名称]<br>
 * CPReportServiceImpl.java<br>
 * <br>
 * [文件描述]<br>
 * 报备相关<br>
 * <br>
 *
 * @author JHSong
 * @version 1.00
 */
@Service
public class AddReportServiceImpl implements AddReportService {

    private Logger logger = LoggerFactory.getLogger(AddReportServiceImpl.class);

    @Autowired
    M2ApiConfig m2ApiConfig;
    @Autowired
    V10ApiConfig v10ApiConfig;
    @Autowired
    private V10BindService v10BindService;
    @Autowired
    private DocumentService documentService;
    @Autowired
    private ReportCommonService reportCommonService;
    @Autowired
    private AuditReportService auditReportService;
    @Autowired
    private PartnerInfoService partnerInfoService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DepartmentDao departmentDao;
    @Autowired
    private PremisesService premisesService;
    @Autowired
    private CustomerPremisesService customerPremisesService;
    @Autowired
    private ReportModelApiService reportModelApiService;
    @Autowired
    private WxTemplateMsgService wxTemplateMsgService;
    @Autowired
    private PremisesOverdueService premisesOverdueService;
    @Autowired
    private ReportModelInfoService reportModelInfoService;
    @Autowired
    private FollowUpListService followUpListService;
    @Autowired
    private CustomerApiService customerApiService;
    @Autowired
    ImportLogService importLogService;

    @Override
    public AddReportResDto addReport(AddReportReqDto reqDto, String assistantAccessToken) {
        AddReportResDto resDto = new AddReportResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            JSONObject errorJson = new JSONObject();
            int successCount = 0;
            int failCount = 0;

            List<AddReportCustomerBean> customerList = reqDto.getCustomerList();
            if (null == customerList) {
                resDto.setResultMsg("报备客户信息不能为空!");
                return resDto;
            }
            Premises premises = premisesService.selectSimpleById(Long.parseLong(reqDto.getPremisesId()));
            if (null == premises || DelFlagEnum.DEL.getNo().equals(premises.getDelFlag())) {
                resDto.setResultMsg("楼盘已无效，无法报备！");
                return resDto;
            }
            if (SaleStatusEnum.type_3.getNo().equals(premises.getSaleStatus())) {
                resDto.setResultMsg("楼盘已下架，无法报备！");
                return resDto;
            }

            PartnerInfo assistantPi = partnerInfoService.selectById(Long.parseLong(reqDto.getUserId()));
            PartnerInfo agentPi = partnerInfoService.selectById(Long.parseLong(reqDto.getStaffId()));
            if (null == agentPi) {
                resDto.setResultMsg("经纪人不存在，报备失败！");
                return resDto;
            }

            StringBuffer sb = new StringBuffer();
            //获取楼盘设置的带看奖
            String reward = premises.getReward();
            //获取楼盘设置的结佣方式
            String commissionWay = premises.getCommissionWay();

            for (AddReportCustomerBean customer : customerList) {
                String mobile = customer.getMobile();
                String name = customer.getName();
                CustomerPremisesDto cpDto = new CustomerPremisesDto();
                cpDto.setMobile(mobile);



                if (!RegexUtil.isMobileNumber(mobile) && mobile.indexOf(StringConstant.THREE_STAR) < 0) {
                    String errorMsg = "手机号:" + mobile + "格式错误!<br/>";
                    sb.append(errorMsg);
                    failCount += 1;
                    continue;
                }


                //报备方式
                if (StringUtils.equals(ReportWayEnum.FULL_NUMBER.getNo(), premises.getReportWay())) {
                    if (mobile.indexOf(StringConstant.THREE_STAR) >= 0) {
                        String errorMsg = "手机号:" + mobile + "，该楼盘【" + premises.getName() + "】仅支持全号报备!<br/>";
                        sb.append(errorMsg);
                        failCount += 1;
                        continue;
                    }
                } else {
                	if(!ReportWayEnum.checkMobile(mobile, premises.getReportWay())) {
                		String errorMsg = "手机号:" + mobile + "，报备方式错误，楼盘【" + premises.getName() + "】报备方式为：" + ReportWayEnum.getDescByNo(premises.getReportWay());
                        sb.append(errorMsg);
                        failCount += 1;
                        continue;
                	}
                }

                //增加客户手机号码全号唯一验证
                if(StringUtils.equals(ReportWayEnum.UNLIMITED.getNo(), premises.getReportWay()) &&  mobile.indexOf(StringConstant.THREE_STAR) < 0){
                    //验证手机号码是否存在
                    CustomerPremises dataResult = customerPremisesService.selectByMobile(customer.getMobile());
                    if(dataResult != null){
                        String errorMsg = "手机号:" + customer.getMobile() + "，已存在，" + ReportWayEnum.getDescByNo(ReportWayEnum.FULL_NUMBER.getNo());
                        sb.append(errorMsg);
                        failCount += 1;
                        continue;
                    }
                }


                //增加客户手机号码前三后四验证
                if(StringUtils.equals(ReportWayEnum.UNLIMITED.getNo(), premises.getReportWay())  &&  mobile.indexOf(StringConstant.THREE_STAR) >=0 ){
                    String mobleValue = customer.getMobile().substring(0,2)+"%%"+customer.getMobile().substring(7,10);
                    //验证手机号码是否存在
                    CustomerPremises dataResult = customerPremisesService.selectByMobile(mobleValue);
                    if(dataResult != null){
                        String errorMsg = "手机号:" +  customer.getMobile() + "，已存在，" + ReportWayEnum.getDescByNo(ReportWayEnum.BEFORE_THREE_AFTER_FOUR.getNo());
                        sb.append(errorMsg);
                        failCount += 1;
                        continue;
                    }
                }
                ReportProtectOverDueDto reportProtectOverDueDto = null;
                ReportValidOverDueDto reportValidOverDueDto = null;
                if (!mobile.contains(StringConstant.THREE_STAR)) {
                    // 1.楼盘 + 手机号 + 到访 + (交易待定、认筹、认购) 存在记录不能报备
                    boolean visitFlag = customerPremisesService.checkVisitRepeat(0L, premises, customer.getMobile());
                    if (visitFlag) {
                        String errorMsg = "手机号为【" + mobile + "】的客户已到访该楼盘【" + premises.getName() + "】,无法再次报备!";
                        sb.append(errorMsg);
                        failCount += 1;
                        continue;
                    }

                    // 2、报备保护逾期校验
                    // 2.1、判断能否报备--> 不能时返回
                    // 2.2、能报备: 判断保护时间应该是多久~
                    reportProtectOverDueDto = premisesOverdueService.checkReportProtect(premises, agentPi, mobile);
                    logger.info("cpreportserviceimpl --> reportProtectOverDueDto: {}", JSONObject.toJSONString(reportProtectOverDueDto));
                    if (!reportProtectOverDueDto.getCanReport().booleanValue()) {
                        String errorMsg = "手机号为【" + mobile + "】的客户在此楼盘【" + premises.getName() + "】处于报备保护期内，目前不可报备<br/>";
                        sb.append(errorMsg);
                        continue;
                    }

                    // 报备有效逾期校验
                    reportValidOverDueDto = premisesOverdueService.checkReportValid(premises, agentPi, mobile);
                    logger.info("cpreportserviceimpl --> reportValidOverDueDto: {}", JSONObject.toJSONString(reportValidOverDueDto));
                    if (!reportValidOverDueDto.getCanReport().booleanValue()) {
                        String errorMsg = "报备无效次数过多,目前不可报备<br/>";
                        sb.append(errorMsg);
                        continue;
                    }
                    //查看经纪人所属渠道商是否与M2绑定
                    Company devCompany = companyService.selectById(premises.getCompanyId());
                    if (ReportExternalConvert.repeatSwitchForM2(devCompany, premises.getProjectCodeM2())) {
                        // 校验手机号在M2的唯一性
                        CommonResDTO commonResDto = reportCommonService.isExistsInM2(premises.getProjectCodeM2(), devCompany.getMerchantCode(), mobile, m2ApiConfig.getM2RequestUrl());
                        if (ResultEnum.FAIL.getNo().equals(commonResDto.getResult())) {
                            BeanUtils.copyProperties(commonResDto, resDto);
                            String errorMsg = resDto.getResultMsg();
                            sb.append(errorMsg);
                            failCount += 1;
                            continue;
                        }
                    }
                }
                //添加报备信息
                cpDto = new CustomerPremisesDto();
                cpDto.setCommissionWay(commissionWay);
                cpDto.setStaffId(Long.parseLong(reqDto.getStaffId()));
                cpDto.setPremisesId(Long.parseLong(reqDto.getPremisesId()));
                cpDto.setMobile(mobile);
                cpDto.setName(name);
                cpDto.setGender(customer.getGender());
                cpDto.setEmail(customer.getEmail());
                cpDto.setConfirmStatus(ConfirmStatusEnum.confirm.getNo());
                cpDto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
                cpDto.setRemark(reqDto.getRemark());
                cpDto.setCompanyId(premises.getCompanyId());
                cpDto.setStaffCompanyId(agentPi.getHigherid());
                //1:已收房源、2: 海外房源
                cpDto.setPremisesSource(premises.getFromSource());
                cpDto.setCommissionAmount("0");
                cpDto.setReward(StringUtils.isEmpty(reward) == true ? new BigDecimal("0") : new BigDecimal(reward));
                cpDto.setDomesticProportion(String.valueOf(premises.getZjCommissionRatio()));
                cpDto.setComplaintsNumber(0L);
                //报备保护时长
                reportCommonService.setReportProtectOverDueTime(cpDto, reportProtectOverDueDto);
                //报备有效时长
                reportCommonService.setReportValidOverDueTime(cpDto, reportValidOverDueDto);
                //待看保护时长
                String saveDays = premises.getSaveDays();
                Calendar calendar = Calendar.getInstance();
                if (StringUtils.isNotEmpty(saveDays)) {
                    try {
                        calendar.add(Calendar.MINUTE, Integer.parseInt(saveDays));
                        cpDto.setLookPeriodTime(calendar.getTime());
                    } catch (Exception e) {
                        cpDto.setLookPeriodTime(calendar.getTime());
                    }
                }
                cpDto.setLongitude(reqDto.getLongitude());
                cpDto.setLatitude(reqDto.getLatitude());
                cpDto.setReportType(reqDto.getReportType());

                //带看保护时间
                Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(Long.parseLong(reqDto.getPremisesId()), premises.getVisitProtect());
                cpDto.setVisitProtectTime(visitProtectCalendar.getTime());
                //期望带看保护时间
                if (StringUtils.isNotBlank(reqDto.getVisitProtectDate())) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    cpDto.setHopeVisitTime(sdf.parse(reqDto.getVisitProtectDate()));
                }
                Long principalId = customerPremisesService.getPricipalId(cpDto.getStaffId());
                cpDto.setPrincipalId(principalId);
                //报备手机号
                cpDto.setReportPhone(agentPi.getPhone());
                if (!TimeUnitTypeEnum.NONE.getNo().equals(premises.getSpecialTimeType()) && StringUtils.isNotBlank(premises.getSpecialTime())) {
                    calendar = Calendar.getInstance();
                    String specialTime = premises.getSpecialTime();
                    calendar.add(Calendar.MINUTE, Integer.parseInt(specialTime));
                    cpDto.setVisitPastTime(calendar.getTime());
                }
                //推荐人
                cpDto.setRecommenderUuid(StringUtils.isEmpty(reqDto.getRecommenderUuid()) ? null : reqDto.getRecommenderUuid());
                cpDto = customerPremisesService.create(cpDto);

                //写带状态跟进记录
                reportCommonService.addReportFollow(cpDto, FollowTypeEnum.CHANNEL.getNo(), "报备客户", String.valueOf(cpDto.getStaffId()), reqDto.getRemark());

                //保存附件
                DocumentDto docDto = new DocumentDto();
                docDto.setObjectId(cpDto.getId());
                docDto.setType(Long.parseLong(DocumentTypeEnum.TYPE_1.getNo()));
                List<AddReportFileBean> fileList = reqDto.getFileList();
                if (null != fileList && fileList.size() > 0) {
                    for (AddReportFileBean fileBean : fileList) {
                        docDto.setUrl(fileBean.getFileName());
                        documentService.create(docDto);
                    }
                }
                successCount++;

                errorJson.put("successCount", successCount);
                errorJson.put("failCount", failCount);
                errorJson.put("failMsg", sb.toString());
                resDto.setResult(ResultEnum.SUCCESS.getNo());
                resDto.setResultMsg(errorJson.toString());

                //当报备为特殊报备时，不发送短信
                if (ReportTypeEnum.type_2.getNo().equals(cpDto.getReportType())) {
                    return resDto;
                }

                //添加自定义报备模板信息
                if (reqDto.getReportModelList() != null && reqDto.getReportModelList().size() > 0) {
                    reportModelApiService.setReportModeInfo(reqDto.getReportModelList(), cpDto.getId());
                }

                //组装短信发送内容Map
                Map<String, String> smsMap = new HashMap<String, String>();
                smsMap.put("premisesName", premises.getName());
                Company company = companyService.selectById(agentPi.getHigherid());
                if (null != company) {
                    smsMap.put("agentCompany", company.getCompanyName());
                }
                Department dept = departmentDao.selectById(agentPi.getDeptId());
                if (null != dept) {
                    smsMap.put("agentDept", dept.getDepartmentName());
                }
                smsMap.put("agentName", agentPi.getAccountName());
                smsMap.put("agentPhone", agentPi.getPhone());
                smsMap.put("cusName", cpDto.getName());
                smsMap.put("mobile", mobile);
                //发送短信
                reportCommonService.sendReportSms(premises, assistantPi, smsMap, cpDto, "经纪人报备");
                //同步V10报备
                v10BindService.syncIntention(cpDto);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //通知驻场人员审核
                wxTemplateMsgService.sendReportCheckTemplateMsg(assistantAccessToken, reqDto.getCompanyUuid()
                        , reqDto.getDomain(), cpDto.getId(), reqDto.getPremisesId(), reqDto.getStaffId()
                        , name, mobile, StringUtils.isEmpty(reqDto.getVisitProtectDate()) ? null : sdf.format(sdf.parse(reqDto.getVisitProtectDate())));

                if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
                    // 判断是否需要自动审核通过
                    AuditCPReqDto auditCPReqDto = new AuditCPReqDto();
                    auditCPReqDto.setId(String.valueOf(cpDto.getId()));
                    auditCPReqDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                    auditCPReqDto.setRemark("报备免审");
                    auditCPReqDto.setUserId(String.valueOf(assistantPi.getId()));
                    auditCPReqDto.setLoginType(SystemIdEnum.DEVELOPERS.getCode());
                    auditCPReqDto.setCreateTime(null);
                    auditCPReqDto.setAffixList(null);
                    auditReportService.auditCP(auditCPReqDto, null, assistantAccessToken);
                }
            }

            errorJson.put("successCount", successCount);
            errorJson.put("failCount", failCount);
            errorJson.put("failMsg", sb.toString());
            resDto.setResultMsg(errorJson.toString());
            resDto.setResult(ResultEnum.SUCCESS.getNo());
        } catch (Exception e) {
            logger.error("报备异常: {}", e);
            resDto.setResult(ResultEnum.FAIL.getNo());
            resDto.setResultMsg("报备异常：" + e.getMessage());
        }
        return resDto;
    }

    @Override
    public AgencyReportResDto agencyReport(AgencyReportReqDto reqDto, String assistantAccessToken) {
        AgencyReportResDto resDto = new AgencyReportResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            //判断报备楼盘是否有效
            Premises premises = premisesService.selectSimpleById(Long.valueOf(reqDto.getPremisesId()));
            if (null == premises || DelFlagEnum.DEL.getNo().equals(premises.getDelFlag())) {
                resDto.setResultMsg("此楼盘已被删除，无法报备!");
                return resDto;
            }
            if (SaleStatusEnum.type_3.getNo().equals(premises.getSaleStatus())) {
                resDto.setResultMsg("楼盘已下架，无法报备！");
                return resDto;
            }
            if (PremisesStatusEnum.type0.getNo().equals(premises.getPremisesStatus()) || PremisesStatusEnum.type2.getNo().equals(premises.getPremisesStatus())){
                resDto.setResultMsg("此楼盘审核状态为待审或审核失败，无法报备!");
                return resDto;
            }
            Map<String, String> smsMap = new HashMap<String, String>();
            smsMap.put("devComp", String.valueOf(premises.getCompanyId()));
            smsMap.put("premisesName", premises.getName());

            PartnerInfo agentPi = partnerInfoService.selectById(Long.parseLong(reqDto.getStaffId()));
            if (null == agentPi) {
                resDto.setResultMsg("报备经纪人未找到!");
                return resDto;
            }

            StringBuffer sb = new StringBuffer();
            smsMap.put("cusName", reqDto.getName());
            smsMap.put("agentName", agentPi.getAccountName());
            smsMap.put("agentPhone", agentPi.getPhone());
            //经纪人公司名称
            Company company = companyService.selectById(agentPi.getHigherid());
            if (null != company) {
                smsMap.put("agentCompany", company.getCompanyName());
            }
            //经纪人部门名称
            Department dept = departmentDao.selectById(agentPi.getDeptId());
            if (null != dept) {
                smsMap.put("agentDept", dept.getDepartmentName());
            }

            //查看经纪人所属渠道商是否与M2绑定
            PartnerInfo assistantPi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
            smsMap.put("assistantName", assistantPi.getAccountName());
            //查看经纪人所属渠道商是否与M2绑定
            Company devCompany = companyService.selectById(premises.getCompanyId());
            String[] premisesIds = reqDto.getPremisesId().split(",");
            for (String premisesId : premisesIds) {
                String mobile = reqDto.getMobile();
                smsMap.put("mobile", mobile);
                CustomerPremisesDto cpDto = new CustomerPremisesDto();
                cpDto.setMobile(mobile);

                ReportProtectOverDueDto reportProtectOverDueDto = null;
                ReportValidOverDueDto reportValidOverDueDto = null;
                if (mobile.indexOf(StringConstant.THREE_STAR) < 0) {
                    boolean visitFlag = customerPremisesService.checkVisitRepeat(0L, premises, mobile);
                    if (visitFlag) {
                        resDto.setResultMsg("该客户已到访该楼盘,无法重复添加!");
                        return resDto;
                    }

                    // 3、报备保护逾期校验
                    // 3.1、判断能否报备--> 不能时返回
                    // 3.2、能报备: 判断保护时间应该是多久~
                    reportProtectOverDueDto = premisesOverdueService.checkReportProtect(premises, agentPi, mobile);
                    logger.info("cpreportserviceimpl --> reportProtectOverDueDto: {}", JSONObject.toJSONString(reportProtectOverDueDto));
                    if (!reportProtectOverDueDto.getCanReport().booleanValue()) {
                        String errorMsg = "手机号为【" + mobile + "】的客户在此楼盘【" + premises.getName() + "】处于报备保护期内，目前不可报备<br/>";
                        sb.append(errorMsg);
                        continue;
                    }

                    // 报备有效逾期校验
                    reportValidOverDueDto = premisesOverdueService.checkReportValid(premises, agentPi, mobile);
                    logger.info("cpreportserviceimpl --> reportValidOverDueDto: {}", JSONObject.toJSONString(reportValidOverDueDto));
                    if (!reportValidOverDueDto.getCanReport().booleanValue()) {
                        String errorMsg = "报备无效次数过多,目前不可报备<br/>";
                        sb.append(errorMsg);
                        continue;
                    }

                    // 校验手机号在M2的唯一性
                    if (ReportExternalConvert.repeatSwitchForM2(devCompany, premises.getProjectCodeM2())) {
                        CommonResDTO commonResDto = reportCommonService.isExistsInM2(premises.getProjectCodeM2(), devCompany.getMerchantCode(), mobile, m2ApiConfig.getM2RequestUrl());
                        if (ResultEnum.FAIL.getNo().equals(commonResDto.getResult())) {
                            BeanUtils.copyProperties(commonResDto, resDto);
                            return resDto;
                        }
                    }
                }

                //带看保护时间
                Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(premises.getId(), premises.getVisitProtect());
                //带看保护时间
                cpDto.setVisitProtectTime(visitProtectCalendar.getTime());
                //报备保护时间
                reportCommonService.setReportProtectOverDueTime(cpDto, reportProtectOverDueDto);
                //报备有效时长
                reportCommonService.setReportValidOverDueTime(cpDto, reportValidOverDueDto);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (StringUtils.isNotEmpty(reqDto.getVisitProtectDate())) {
                    Date date = sdf.parse(reqDto.getVisitProtectDate());
                    //期望带看时间
                    cpDto.setHopeVisitTime(date);
                }
                //从楼盘中获取佣金、带看奖、结佣方式
                String reward = premises.getReward();
                String commissionWay = premises.getCommissionWay();
                cpDto.setCommissionWay(commissionWay);
                cpDto.setCommission("0");
                cpDto.setReward(StringUtils.isEmpty(reward) == true ? new BigDecimal("0") : new BigDecimal(reward));
                cpDto.setStaffId(Long.parseLong(reqDto.getStaffId()));
                cpDto.setPremisesId(Long.valueOf(premisesId));
                cpDto.setCreateTime(Calendar.getInstance().getTime());
                cpDto.setName(reqDto.getName());
                cpDto.setGender(reqDto.getGender());
                cpDto.setEmail(null);
                cpDto.setConfirmStatus(ConfirmStatusEnum.confirm.getNo());
                cpDto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
                cpDto.setRemark(reqDto.getRemark());
                cpDto.setCompanyId(premises.getCompanyId());
                cpDto.setPartnerId(Long.parseLong(reqDto.getUserId()));
                cpDto.setStaffCompanyId(agentPi.getHigherid());
                //设置楼盘来源
                cpDto.setPremisesSource(premises.getFromSource());
                cpDto.setCommissionAmount("0");

                Long principal = customerPremisesService.getPricipalId(cpDto.getStaffId());
                cpDto.setPrincipalId(principal);
                //报备手机号
                cpDto.setReportPhone(assistantPi.getPhone());
                Calendar calendar = Calendar.getInstance();
                if (!TimeUnitTypeEnum.NONE.getNo().equals(premises.getSpecialTimeType()) && StringUtils.isNotBlank(premises.getSpecialTime())) {
                    String specialTime = premises.getSpecialTime();
                    calendar.add(Calendar.MINUTE, Integer.parseInt(specialTime));
                    cpDto.setVisitPastTime(calendar.getTime());
                }
                //推荐人
                cpDto.setRecommenderUuid(StringUtils.isEmpty(reqDto.getRecommenderUuid()) ? null : reqDto.getRecommenderUuid());
                cpDto = customerPremisesService.create(cpDto);

                //添加自定义报备模板信息
                if (reqDto.getReportModelList() != null && reqDto.getReportModelList().size() > 0) {
                    reportModelApiService.setReportModeInfo(reqDto.getReportModelList(), cpDto.getId());
                }

                //添加报备
                reportCommonService.addReportFollow(cpDto, FollowTypeEnum.CHANNEL.getNo(), "代报备客户", reqDto.getStaffId(), reqDto.getRemark());
                //发送报备短信
                reportCommonService.sendReportSms(premises, assistantPi, smsMap, cpDto, "案场代报备");
                //报备信息同步到V10
                v10BindService.syncIntention(cpDto);
                //通知驻场人员审核
                String visitTime = "";
                if (StringUtils.isNotBlank(reqDto.getVisitProtectDate())) {
                    visitTime = sdf.format(sdf.parse(reqDto.getVisitProtectDate()));
                }
                wxTemplateMsgService.sendReportCheckTemplateMsg(assistantAccessToken, reqDto.getCompanyUuid()
                        , reqDto.getDomain(), cpDto.getId(), reqDto.getPremisesId(), reqDto.getStaffId()
                        , reqDto.getName(), reqDto.getMobile(), StringUtils.isEmpty(reqDto.getVisitProtectDate()) ? null : sdf.format(sdf.parse(reqDto.getVisitProtectDate())));

                if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
                    // 判断是否需要自动审核通过
                    AuditCPReqDto auditCPReqDto = new AuditCPReqDto();
                    auditCPReqDto.setId(String.valueOf(cpDto.getId()));
                    auditCPReqDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                    auditCPReqDto.setRemark("报备免审");
                    auditCPReqDto.setUserId(String.valueOf(assistantPi.getId()));
                    auditCPReqDto.setLoginType(SystemIdEnum.DEVELOPERS.getCode());
                    auditCPReqDto.setCreateTime(null);
                    auditCPReqDto.setAffixList(null);
                    auditReportService.auditCP(auditCPReqDto, null, assistantAccessToken);
                }
            }
            resDto.setResult(ResultEnum.SUCCESS.getNo());
            resDto.setResultMsg(sb.toString());
        } catch (Exception ex) {
            logger.error("代报备异常: {}", ex);
            resDto.setResultMsg("代报备异常: " + ex.getMessage());
        }
        return resDto;
    }

    @Override
    public ReportAgainResDto reportAgain(ReportAgainReqDto reqDto, String assistantAccessToken) {
        ReportAgainResDto resDto = new ReportAgainResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            CustomerPremises cusPre = customerPremisesService.selectById(Long.valueOf(reqDto.getCusPreId()));
            if (null == cusPre) {
                resDto.setResultMsg("无效报备记录,不能再次发起!");
                return resDto;
            }
            if (null != cusPre.getAfreshNum()) {
                resDto.setResultMsg("已发起重新报备,不能再次发起!");
                return resDto;
            }
            Premises premises = premisesService.selectSimpleById(cusPre.getPremisesId());
            if (null == premises || DelFlagEnum.DEL.getNo().equals(premises.getDelFlag())) {
                resDto.setResultMsg("楼盘无效,不能再次发起!");
                return resDto;
            }
            if (SaleStatusEnum.type_3.getNo().equals(premises.getSaleStatus())) {
                resDto.setResultMsg("楼盘已下架，无法报备！");
                return resDto;
            }
            PartnerInfo assistantPi = partnerInfoService.selectById(Long.valueOf(reqDto.getUserId()));
            PartnerInfo agentPi = partnerInfoService.selectById(cusPre.getStaffId());
            ReportProtectOverDueDto reportProtectOverDueDto = null;
            ReportValidOverDueDto reportValidOverDueDto = null;
            String mobile = cusPre.getMobile();
            if (mobile.indexOf(StringConstant.THREE_STAR) < 0) {
                boolean visitFlag = customerPremisesService.checkVisitRepeat(0L, premises, cusPre.getMobile());
                if (visitFlag) {
                    resDto.setResultMsg("手机号为【" + mobile + "】的客户已到访该楼盘【" + premises.getName() + "】,无法再次报备!");
                    return resDto;
                }

                // 3、报备保护逾期校验
                // 3.1、判断能否报备--> 不能时返回
                // 3.2、能报备: 判断保护时间应该是多久~
                reportProtectOverDueDto = premisesOverdueService.checkReportProtect(premises, agentPi, mobile);
                logger.info("cpreportserviceimpl --> reportProtectOverDueDto: {}", JSONObject.toJSONString(reportProtectOverDueDto));
                if (!reportProtectOverDueDto.getCanReport().booleanValue()) {
                    String errorMsg = "手机号为【" + mobile + "】的客户在此楼盘【" + premises.getName() + "】处于报备保护期内，目前不可报备<br/>";
                    resDto.setResultMsg(errorMsg);
                    return resDto;
                }

                // 报备有效逾期校验
                reportValidOverDueDto = premisesOverdueService.checkReportValid(premises, agentPi, mobile);
                logger.info("cpreportserviceimpl --> reportValidOverDueDto: {}", JSONObject.toJSONString(reportValidOverDueDto));
                if (!reportValidOverDueDto.getCanReport().booleanValue()) {
                    String errorMsg = "报备无效次数过多,目前不可报备<br/>";
                    resDto.setResultMsg(errorMsg);
                    return resDto;
                }
            }

            //重新发起生成一条新的记录
            CustomerPremisesDto cpDto = new CustomerPremisesDto();
            BeanUtils.copyProperties(cusPre, cpDto);
            cpDto.setId(null);
            cpDto.setMobile(mobile);
            Date hopeVisitTime = cpDto.getHopeVisitTime();
            Calendar calendar = Calendar.getInstance();
            //期望带看时间小于系统当前时间。期望带看时间以当前时间为加一天 todo 时间换算
            if (Objects.nonNull(hopeVisitTime) && hopeVisitTime.getTime() < calendar.getTime().getTime()) {
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                cpDto.setHopeVisitTime(calendar.getTime());
            }

            //报备有效时长
            reportCommonService.setReportValidOverDueTime(cpDto, reportValidOverDueDto);

            cpDto.setDisableType("");
            cpDto.setComplaintsNumber(null);
            cpDto.setStaffCompanyId(cusPre.getStaffCompanyId());
            cpDto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
            cpDto.setConfirmStatus(ConfirmStatusEnum.confirm.getNo());
            cpDto.setPremisesSource(cusPre.getPremisesSource());
            cpDto.setAfreshNum(0l);
            //报备手机号
            cpDto.setReportPhone(agentPi.getPhone());
            if (!TimeUnitTypeEnum.NONE.getNo().equals(premises.getSpecialTimeType()) && StringUtils.isNotBlank(premises.getSpecialTime())) {
                calendar = Calendar.getInstance();
                String specialTime = premises.getSpecialTime();
                calendar.add(Calendar.MINUTE, Integer.parseInt(specialTime));
                cpDto.setVisitPastTime(calendar.getTime());
            }
            cpDto = customerPremisesService.create(cpDto);
            //设置报备模板
            ReportModelInfoDto reportModelInfoDto = new ReportModelInfoDto();
            reportModelInfoDto.setReportId(cusPre.getId());
            reportModelInfoDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
            List<ReportModelInfo> reportModelInfoList = reportModelInfoService.selectListByDto(reportModelInfoDto);
            if (reportModelInfoList != null && reportModelInfoList.size() > 0) {
                reportModelApiService.addReportModeInfo(reportModelInfoList, cusPre.getId());
            }

            //重新发起后将原纪录重新发起次数+1
            CustomerPremisesDto entity = new CustomerPremisesDto();
            entity.setId(cusPre.getId());
            entity.setAfreshNum(1L);
            customerPremisesService.update(entity);

            //写带状态跟进记录
            reportCommonService.addReportFollow(cpDto, FollowTypeEnum.CHANNEL.getNo(), "报备客户", String.valueOf(cpDto.getStaffId()), null);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //通知驻场人员审核
            String hopeVisitStr = "";
            if (Objects.nonNull(hopeVisitTime)) {
                hopeVisitStr = sdf.format(hopeVisitTime);
            }
            wxTemplateMsgService.sendReportCheckTemplateMsg(assistantAccessToken, reqDto.getCompanyUuid()
                    , reqDto.getDomain(), cpDto.getId(), cusPre.getPremisesId() + "", cusPre.getStaffId() + ""
                    , cusPre.getName(), cusPre.getMobile(), hopeVisitStr);

            if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
                // 判断是否需要自动审核通过
                AuditCPReqDto auditCPReqDto = new AuditCPReqDto();
                auditCPReqDto.setId(String.valueOf(cpDto.getId()));
                auditCPReqDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
                auditCPReqDto.setRemark("报备免审");
                auditCPReqDto.setUserId(String.valueOf(assistantPi.getId()));
                auditCPReqDto.setLoginType(SystemIdEnum.DEVELOPERS.getCode());
                auditCPReqDto.setCreateTime(null);
                auditCPReqDto.setAffixList(null);
                auditReportService.auditCP(auditCPReqDto, null, assistantAccessToken);
            }

            resDto.setResult(ResultEnum.SUCCESS.getNo());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return resDto;
    }

    @Override
    public CompletePhoneResDto completePhone(CompletePhoneReqDto reqDto) {
        CompletePhoneResDto resDto = new CompletePhoneResDto();
        resDto.setResult(ResultEnum.FAIL.getNo());
        try {
            //1、判断记录是否存在
            //2、判断记录是否为未确认状态
            //3、判断修改的手机号是否存在
            //4、修改记录手机号码
            //5、记录状态变更为报备有效
            //6、添加跟进
            CustomerPremises cusPre = customerPremisesService.selectById(Long.valueOf(reqDto.getId()));
            if (null == cusPre) {
                resDto.setResultMsg("报备记录不存在!");
                return resDto;
            }

            /**
             * 补全号码: 校验该号码是否存在已到访且交易未完成的报备
             */
            Premises premises = premisesService.selectSimpleById(cusPre.getPremisesId());
            String customerStatus = cusPre.getCustomerStatus();
            //校验是否可以进行报备
            if (null == premises) {
                resDto.setResultMsg("报备所处楼盘已不存在!");
                return resDto;
            }
            ReportProtectOverDueDto reportProtectOverDueDto = null;
            ReportValidOverDueDto reportValidOverDueDto = null;
            String mobile = reqDto.getMobile();
            if (mobile.indexOf(StringConstant.THREE_STAR) < 0) {
                boolean flag = customerPremisesService.checkVisitRepeat(Long.valueOf(reqDto.getId()), premises, mobile);
                if (flag) {
                    resDto.setResultMsg("此号码所属客户已到访该楼盘,无法重复添加!");
                    return resDto;
                }

                PartnerInfo agentPi = partnerInfoService.selectById(cusPre.getStaffId());

                // 3、报备保护逾期校验
                // 3.1、判断能否报备--> 不能时返回
                // 3.2、能报备: 判断保护时间应该是多久~
                reportProtectOverDueDto = premisesOverdueService.checkReportProtect(premises, agentPi, mobile);
                logger.info("cpreportserviceimpl --> reportProtectOverDueDto: {}", JSONObject.toJSONString(reportProtectOverDueDto));
                if (!reportProtectOverDueDto.getCanReport().booleanValue()) {
                    String errorMsg = "手机号为【" + mobile + "】的客户在此楼盘【" + premises.getName() + "】处于报备保护期内，目前不可报备<br/>";
                    resDto.setResultMsg(errorMsg);
                    return resDto;
                }

                // 报备有效逾期校验
                reportValidOverDueDto = premisesOverdueService.checkReportValid(premises, agentPi, mobile);
                logger.info("cpreportserviceimpl --> reportValidOverDueDto: {}", JSONObject.toJSONString(reportValidOverDueDto));
                if (!reportValidOverDueDto.getCanReport().booleanValue()) {
                    String errorMsg = "报备无效次数过多,目前不可报备<br/>";
                    resDto.setResultMsg(errorMsg);
                    return resDto;
                }
            }
            CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
            cusPreDto.setId(cusPre.getId());
            cusPreDto.setMobile(mobile);
            //报备保护时长
            reportCommonService.setReportProtectOverDueTime(cusPreDto, reportProtectOverDueDto);
            //报备有效时长
            reportCommonService.setReportValidOverDueTime(cusPreDto, reportValidOverDueDto);
            int updateCount = customerPremisesService.update(cusPreDto);
            if (updateCount > 0) {
                //添加跟进记录
                editReportToAddFollow(cusPre, FollowTypeEnum.DEVELOPERS.getNo(), "补全号码", "");
                // 更新客户信息
                customerApiService.completePhone2EditCustomer(cusPre.getId());
            } else {
                resDto.setResultMsg("补全号码失败!");
            }
            resDto.setResult(ResultEnum.SUCCESS.getNo());
        } catch (Exception ex) {
            logger.error("补全号码失败: {}", ex);
            resDto.setResultMsg("补全号码失败: " + ex.getMessage());
        }
        return resDto;
    }


    /**
     * 修改报备添加跟进
     *
     * @param cusPre
     * @param followType
     * @param reportPrefix
     * @param remark
     */
    private void editReportToAddFollow(CustomerPremises cusPre, String followType, String reportPrefix, String remark) {
        FollowUpListDto fulDto = new FollowUpListDto();
        fulDto.setCreateTime(Calendar.getInstance().getTime());
        fulDto.setCustomerPremisesId(cusPre.getId());
        fulDto.setOldConfirmStatus(cusPre.getConfirmStatus());
        fulDto.setNewConfirmStatus(cusPre.getConfirmStatus());
        fulDto.setOldCustomerStatus(cusPre.getCustomerStatus());
        fulDto.setNewCustomerStatus(cusPre.getCustomerStatus());
        fulDto.setStaffId(cusPre.getStaffId());
        fulDto.setFollowType(followType);
        fulDto.setRemark("【" + reportPrefix + "】" + remark);
        followUpListService.create(fulDto);
    }

    @Override
    //@Async
    public Map<String, Object> addBatchCusPre(Map<String, String> batchMap, boolean repeatSwitch, Premises premises, String userId) {
        Map<String, Object> returnMap = new HashMap<>();
        String batchId = batchMap.get("batchId");
        String visitProtectDate = batchMap.get("visitProtectDate");
        String remark = batchMap.get("remark");
        String recommenderUuid = batchMap.get("recommenderUuid");

        ImportLogDto importLogDto = new ImportLogDto();
        importLogDto.setBatchId(batchId);
        ImportLog importLog = importLogService.selectByDto(importLogDto);
        if (null == importLog || StringUtils.isBlank(importLog.getOriginalData())) {
            returnMap.put("result", ResultEnum.FAIL.getNo());
            returnMap.put("errorMsg", "未找到上传记录");
            return returnMap;
        }

        String originalData = importLog.getOriginalData();
        JSONArray jsonArray = JSONArray.parseArray(originalData);
        if (null == jsonArray || jsonArray.size() == 0) {
            returnMap.put("result", ResultEnum.FAIL.getNo());
            returnMap.put("errorMsg", "未找到上传记录");
            return returnMap;
        }

        int mapListSize = jsonArray.size();
        //统计错误
        JSONObject noticeJson = new JSONObject();
        JSONArray errorArray = new JSONArray();
        noticeJson.put("total", mapListSize);

        // 当前登陆人
        PartnerInfo loginUser = partnerInfoService.selectById(Long.valueOf(userId));

        // 校验所有数据
        List<Long> staffIds = new ArrayList<>();
        List<String> customerPhones = new ArrayList<>();
        for (int ii = 0; ii < mapListSize; ii++) {
            JSONObject jsonObject = (JSONObject) jsonArray.get(ii);
            if (null == jsonObject.get("staffId") || null == jsonObject.get("mobile")) {
                continue;
            }
            Integer staffId = (Integer) jsonObject.get("staffId");
            String mobile = (String) jsonObject.get("mobile");
            staffIds.add(Long.valueOf(staffId));
            if (StringUtils.isNotBlank(mobile)) {
                customerPhones.add(mobile);
            }
        }
        CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
        cusPreDto.setPremisesId(premises.getId());
        cusPreDto.setStaffIds(staffIds);
        cusPreDto.setCustomerPhones(customerPhones);
        List<CustomerPremisesDto> customerPremisesList = customerPremisesService.selectImportRepeatListByDto(cusPreDto);
        Map<String, Long> existsShowMap = new HashMap<>();
        Map<String, Long> existsHideMap = new HashMap<>();
        if (null != customerPremisesList && customerPremisesList.size() > 0) {
            for (CustomerPremisesDto existsCusPreDto : customerPremisesList) {
                if (existsCusPreDto.getMobile().indexOf(StringConstant.THREE_STAR) < 0) {
                    // 楼盘+经纪人+手机号+客户状态(0,6)
                    String showMapKey = existsCusPreDto.getPremisesId() + "-" + existsCusPreDto.getStaffId() + "-" + existsCusPreDto.getMobile() + "-" + existsCusPreDto.getCustomerStatus();
                    existsShowMap.put(showMapKey, existsCusPreDto.getId());
                } else {
                    // 楼盘 + 经纪人 + 手机号 + 客户姓名 + 客户状态(0)
                    String hideMapKey = existsCusPreDto.getPremisesId() + "-" + existsCusPreDto.getStaffId() + "-" + existsCusPreDto.getMobile() + "-" + existsCusPreDto.getName() + "-" + existsCusPreDto.getCustomerStatus();
                    existsHideMap.put(hideMapKey, existsCusPreDto.getId());
                }
            }
        }

        // 重复待更新数据
        List<Long> updateIds = new ArrayList<>();

        for (int ii = 0; ii < mapListSize; ii++) {
            long recordStart = System.currentTimeMillis();
            logger.info("record 【" + ii + "】 start, time = " + recordStart);
            JSONObject jsonObject = (JSONObject) jsonArray.get(ii);
            if (Objects.isNull(jsonObject)) {
                continue;
            }
            try {
                String agentName = StringUtils.defaultIfBlank(String.valueOf(jsonObject.get("agentName")).trim(), "");
                String agentPhone = StringUtils.defaultIfBlank(String.valueOf(jsonObject.get("agentPhone")).trim(), "");
                String name = StringUtils.defaultIfBlank(String.valueOf(jsonObject.get("name")).trim(), "");
                String mobile = StringUtils.defaultIfBlank(String.valueOf(jsonObject.get("mobile")).trim(), "");
                String gender = StringUtils.defaultIfBlank(String.valueOf(jsonObject.get("gender")).trim(), "");
                Integer staffId = Integer.valueOf(String.valueOf(jsonObject.get("staffId")).trim());
                Integer staffCompany = Integer.valueOf(String.valueOf(jsonObject.get("staffCompany")).trim());
                //校验经纪人姓名和手机号是否存在及手机号格式校验
                if (StringUtils.isBlank(agentName) || StringUtils.isBlank(agentPhone)) {
                    jsonObject.put("error", "经纪人姓名或手机不能为空!");
                    errorArray.add(jsonObject);
                    continue;
                } else if (!PatternUtil.isMobile(agentPhone)) {
                    //手机号格式校验
                    jsonObject.put("error", "经纪人手机格式错误!");
                    errorArray.add(jsonObject);
                    continue;
                }

                // 校验客户姓名和手机号是否存在及校验全号报备手机号格式是否正确
                if (StringUtils.isBlank(name) || StringUtils.isBlank(mobile) || StringUtils.isBlank(gender)) {
                    jsonObject.put("error", "客户姓名或手机号或性别不能为空");
                    errorArray.add(jsonObject);
                    continue;
                } else if (!mobile.contains(StringConstant.THREE_STAR) && !PatternUtil.isMobile(mobile)) {
                    jsonObject.put("error", "客户手机格式不对!");
                    errorArray.add(jsonObject);
                    continue;
                }
                if (StringUtils.equals(ReportWayEnum.FULL_NUMBER.getNo(), premises.getReportWay())) {
                    if (mobile.indexOf(StringConstant.THREE_STAR) >= 0) {
                        jsonObject.put("error", "楼盘不支持隐号报备!");
                        errorArray.add(jsonObject);
                        continue;
                    }
                } else {
                    if(!ReportWayEnum.checkMobile(mobile, premises.getReportWay())) {
                        String reportWay = premises.getReportWay();
                        if(StringUtils.isBlank(reportWay)){
                            reportWay = ReportWayEnum.UNLIMITED.getNo();
                        }
                        jsonObject.put("error", "楼盘仅支持"+ReportWayEnum.getDescByNo(reportWay)+"方式报备!");
                        errorArray.add(jsonObject);
                        continue;
                    }
                }
                if (StringUtils.isBlank(visitProtectDate)) {
                    jsonObject.put("error", "预计到访时间不能为空");
                    errorArray.add(jsonObject);
                    continue;
                }

                // 登陆人公司与导入数据的经纪人是否同一公司人员
                if (!String.valueOf(loginUser.getHigherid()).equals(String.valueOf(staffCompany))) {
                    String msg = "经纪人属于其他公司,不能创建报备!";
                    jsonObject.put("error", msg);
                    errorArray.add(jsonObject);
                    continue;
                }
                if (mobile.indexOf(StringConstant.THREE_STAR) < 0) {
                    // 全号校验
                    // 楼盘+经纪人+手机号+客户状态(0,6)
                    String wholeAuditKey = premises.getId() + "-" + staffId + "-" + mobile + "-0";
                    String wholeTradeKey = premises.getId() + "-" + staffId + "-" + mobile + "-6";
                    Long updateId = existsShowMap.get(wholeTradeKey);
                    if (null == updateId) {
                        // 不存在待交易数据, 继续校验是否存在待更新数据
                        updateId = existsShowMap.get(wholeAuditKey);
                        if (null != updateId) {
                            updateIds.add(updateId);
                            continue;
                        }
                    } else {
                        jsonObject.put("error", "客户已到访且交易未完结,无法再次报备!");
                        errorArray.add(jsonObject);
                        continue;
                    }
                } else {
                    // 隐号校验
                    // 楼盘 + 经纪人 + 手机号 + 客户姓名 + 客户状态(0)
                    String hideAuditKey = premises.getId() + "-" + staffId + "-" + mobile + "-" + name + "-0";
                    Long updateId = existsHideMap.get(hideAuditKey);
                    if (null != updateId) {
                        updateIds.add(updateId);
                        continue;
                    }
                }

                gender = GenderEnum.MALE.getNo();
                if (StringUtils.isNotBlank(gender) && GenderEnum.FEMALE.getDes().equals(gender)) {
                    gender = GenderEnum.FEMALE.getNo();
                }
                // 添加报备
                addBatchReprot(premises, String.valueOf(staffId), name, mobile, gender, String.valueOf(staffCompany), visitProtectDate, remark, recommenderUuid);
            } catch (Exception ex) {
                logger.error("import customer premises error: {}", ex);
                jsonObject.put("error", "导入异常:" + ex.getMessage());
                errorArray.add(jsonObject);
            }
        }

        // 更新待处理数据
        updateCusPre(premises, updateIds, visitProtectDate, remark, batchId);

        if (errorArray.size() > 0) {
            importLogDto = new ImportLogDto();
            importLogDto.setId(importLog.getId());
            importLogDto.setErrorData(errorArray.toJSONString());
            importLogService.update(importLogDto);
        }
        //导入完成做个统计说明
        int totalCount = mapListSize;
        int successCount = mapListSize - errorArray.size();
        int failureCount = errorArray.size();
        boolean hasErrorRecord = failureCount > 0 ? true : false;
        String msg = "总计:" + totalCount + ",成功:" + successCount + "条,失败:" + failureCount + "条";
        returnMap.put("result", ResultEnum.SUCCESS.getNo());
        returnMap.put("showMsg", msg);
        returnMap.put("hasErrorRecord", hasErrorRecord);

        return returnMap;
    }

    @Async
    public void addBatchReprot(Premises premises, String staffId, String name, String mobile, String gender, String staffCompany, String visitProtectDate, String remark, String recommenderUuid) {
        //添加报备
        CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
        cusPreDto.setStaffId(Long.valueOf(staffId));
        cusPreDto.setPremisesId(premises.getId());
        cusPreDto.setName(name);
        cusPreDto.setMobile(mobile);
        cusPreDto.setGender(gender);
        cusPreDto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
        if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
            // 导入免审只需添加跟进即可.无需进行消息等发送
            cusPreDto.setCustomerStatus(CustomerStatusEnum.not_visited.getNo());
        }

        cusPreDto.setConfirmStatus(ConfirmStatusEnum.confirm.getNo());
        cusPreDto.setCompanyId(premises.getCompanyId());
        cusPreDto.setPartnerId(null);
        cusPreDto.setStaffCompanyId(Long.valueOf(staffCompany));
        cusPreDto.setPremisesSource(premises.getFromSource());
        cusPreDto.setCommissionAmount("0");
        cusPreDto.setDomesticProportion(String.valueOf(premises.getZjCommissionRatio()));
        cusPreDto.setComplaintsNumber(0L);
        cusPreDto.setRecommenderUuid(recommenderUuid);
        Long reportProtect = premises.getReportProtect();
        Calendar calendar = Calendar.getInstance();
        cusPreDto.setReportPeriodTime(calendar.getTime());
        if (Objects.nonNull(reportProtect)) {
            calendar.add(Calendar.MINUTE, Integer.valueOf(String.valueOf(reportProtect)));
            cusPreDto.setReportPeriodTime(calendar.getTime());
        }
        //待看保护时长
        String saveDays = premises.getSaveDays();
        calendar = Calendar.getInstance();
        if (StringUtils.isNotEmpty(saveDays)) {
            try {
                calendar.add(Calendar.MINUTE, Integer.parseInt(saveDays));
                cusPreDto.setLookPeriodTime(calendar.getTime());
            } catch (Exception e) {
                cusPreDto.setLookPeriodTime(calendar.getTime());
            }
        }
        cusPreDto.setReportType(ReportTypeEnum.type_1.getNo());
        //带看保护时间

        Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(premises.getId(), premises.getVisitProtect());
        cusPreDto.setVisitProtectTime(visitProtectCalendar.getTime());
        try {
            if (StringUtils.isNotBlank(visitProtectDate)) {
                cusPreDto.setHopeVisitTime(DateUtils.stringToDate(visitProtectDate, DateStyle.YYYY_MM_DD_HH_MM.getValue()));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        cusPreDto.setReward(StringUtils.isEmpty(premises.getReward()) == true ? new BigDecimal("0") : new BigDecimal(premises.getReward()));
        cusPreDto.setCommissionWay(premises.getCommissionWay());
        cusPreDto.setRemark(remark);
        //报备手机号
        PartnerInfo report = partnerInfoService.selectById(Long.valueOf(staffId));
        cusPreDto.setReportPhone(report.getPhone());
        cusPreDto = customerPremisesService.create(cusPreDto);

        //写带状态跟进记录
        FollowUpListDto fulDto = new FollowUpListDto();
        fulDto.setCreateTime(Calendar.getInstance().getTime());
        fulDto.setCustomerPremisesId(cusPreDto.getId());
        fulDto.setNewConfirmStatus(ConfirmStatusEnum.confirm.getNo());
        fulDto.setNewCustomerStatus(CustomerStatusEnum.normal.getNo());
        fulDto.setStaffId(cusPreDto.getStaffId());
        fulDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
        if (StringUtils.isNotBlank(remark)) {
            fulDto.setRemark("【导入报备】" + remark);
        } else {
            fulDto.setRemark("【导入报备】");
        }
        followUpListService.create(fulDto);
        if (FreeAuditEnum.FREE_REPORT_AUDIT.getNo().equals(premises.getFreeAudit())) {
            // 导入免审跟进记录
            fulDto = new FollowUpListDto();
            fulDto.setCreateTime(Calendar.getInstance().getTime());
            fulDto.setCustomerPremisesId(cusPreDto.getId());
            fulDto.setOldCustomerStatus(CustomerStatusEnum.normal.getNo());
            fulDto.setNewCustomerStatus(CustomerStatusEnum.not_visited.getNo());
            fulDto.setOldConfirmStatus(ConfirmStatusEnum.confirm.getNo());
            fulDto.setNewConfirmStatus(ConfirmStatusEnum.confirm.getNo());
            fulDto.setStaffId(cusPreDto.getStaffId());
            fulDto.setFollowType(FollowTypeEnum.DEVELOPERS.getNo());
            fulDto.setRemark("【导入报备】报备免审" + remark);
            followUpListService.create(fulDto);
        }
    }

    /**
     * 修改批量上传重复报备数据及相关跟进
     *
     * @param premises
     * @param updateIds
     * @param visitProtectDate
     * @param remark
     */
    @Async
    public void updateCusPre(Premises premises, List<Long> updateIds, String visitProtectDate, String remark, String batchId) {
        try {
            String updateIdsStr = "";
            if (null != updateIds && updateIds.size() > 0) {
                for (int ii = 0; ii < updateIds.size(); ii++) {
                    updateIdsStr += String.valueOf(updateIds.get(ii));
                    if (ii < updateIds.size() - 1) {
                        updateIdsStr += ",";
                    }
                }
            }
            if (StringUtils.isNotBlank(updateIdsStr)) {
                CustomerPremisesDto cusPreDto = new CustomerPremisesDto();
                cusPreDto.setIds(updateIdsStr);
                Long reportProtect = premises.getReportProtect();
                Calendar calendar = Calendar.getInstance();
                cusPreDto.setReportPeriodTime(calendar.getTime());
                if (Objects.nonNull(reportProtect)) {
                    calendar.add(Calendar.MINUTE, Integer.valueOf(String.valueOf(reportProtect)));
                    cusPreDto.setReportPeriodTime(calendar.getTime());
                }
                //待看保护时长
                String saveDays = premises.getSaveDays();
                calendar = Calendar.getInstance();
                if (StringUtils.isNotEmpty(saveDays)) {
                    try {
                        calendar.add(Calendar.MINUTE, Integer.parseInt(saveDays));
                        cusPreDto.setLookPeriodTime(calendar.getTime());
                    } catch (Exception e) {
                        cusPreDto.setLookPeriodTime(calendar.getTime());
                    }
                }
                //带看保护时间
                Calendar visitProtectCalendar = customerPremisesService.getVisitProtectCalendar(premises.getId(), premises.getVisitProtect());
                cusPreDto.setVisitProtectTime(visitProtectCalendar.getTime());
                try {
                    if (StringUtils.isNotBlank(visitProtectDate)) {
                        cusPreDto.setHopeVisitTime(DateUtils.stringToDate(visitProtectDate, DateStyle.YYYY_MM_DD_HH_MM.getValue()));
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                cusPreDto.setCreateTime(Calendar.getInstance().getTime());
                cusPreDto.setRemark(remark);
                int count = customerPremisesService.edits(cusPreDto, updateIdsStr);
                logger.info("batchId = " + batchId + ", 更新重复报备: " + count + "笔");
                //写带状态跟进记录
                FollowUpListDto fulDto = new FollowUpListDto();
                fulDto.setCusPreIds(updateIds);
                List<FollowUpList> fulList = followUpListService.selectListByIds(fulDto);
                Map<String, FollowUpList> fulListMap = new HashMap<>();
                if (null != fulList && fulList.size() > 0) {
                    for (FollowUpList ful : fulList) {
                        fulListMap.put(String.valueOf(ful.getCustomerPremisesId()), ful);
                    }
                }

                for (Map.Entry<String, FollowUpList> entry : fulListMap.entrySet()) {
                    FollowUpList newFul = entry.getValue();
                    FollowUpListDto newFulDto = new FollowUpListDto();
                    BeanUtils.copyProperties(newFul, newFulDto);
                    newFulDto.setId(null);
                    newFulDto.setCreateTime(null);
                    newFulDto.setRemark("【导入重复报备】:" + remark);
                    followUpListService.create(newFulDto);
                }
                //fulDto = new FollowUpListDto();
                //fulDto.setCusPreIds(updateIds);
                //fulDto.setCreateTime(Calendar.getInstance().getTime());
                //count = followUpListService.updateByCusPreIds(fulDto);
                logger.info("batchId = {}, 更新重复报备跟进: {} 笔", batchId, count);
            }
        } catch (Exception ex) {
            logger.error("batchId = {}, 更新重复报备失败: {}", batchId, ex);
        }
    }
}
